package ru.jexp.tl.session;

import java.sql.SQLException;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;

import oracle.toplink.internal.databaseaccess.DatabaseAccessor;
import oracle.toplink.threetier.ClientSession;
import oracle.toplink.threetier.ConnectionPool;
import oracle.toplink.threetier.ServerSession;
import ru.jexp.tl.descriptor.TLProject;

public class TLSession {
	private ServerSession server;
	private TLProject project;
	private static TLSession instance;

	public static void createInstance(TLProject project) {
		if (instance == null) {
			instance = new TLSession();
			instance.project = project;
		}
	}

	public final ClientSession acquireClientSession() {
		if (server == null)
			init();
		else

			try {
				checkConnection();
			} catch (SQLException e) {
				e.printStackTrace();
			}

		ClientSession cs = server.acquireClientSession();
		return cs;
	}

	private synchronized void checkConnection() throws SQLException {
		Map en = server.getConnectionPools();
		for (Iterator iterator = en.keySet().iterator(); iterator.hasNext();) {
			ConnectionPool connectionPool = (ConnectionPool) en.get(iterator
					.next());
			Vector connectionsAvailable = connectionPool
					.getConnectionsAvailable();
			if (connectionsAvailable.isEmpty()) {
				connectionPool.shutDown();
				connectionPool.startUp();
			} else
				for (Iterator iterator2 = connectionsAvailable.iterator(); iterator2
						.hasNext();) {
					DatabaseAccessor conn = (DatabaseAccessor) iterator2.next();
					if (!conn.getConnection().isValid(0)) {
						System.out.println("CONN NOT CONNECTED");
						connectionPool.shutDown();
						connectionPool.startUp();
						break;
					}
				}
		}
	}

	public void init() {
		if (server == null) {
			server = (ServerSession) project.createServerSession();
			server.getSequencingControl().setShouldUseSeparateConnection(true);
			server.logMessages();
			server.login();
		}
	}

	public static final TLSession getInstance() {
		return instance;
	}

}
